import _ from 'lodash';

/**
 * 懒加载，controller.js里定义了disableCache()，返回值为false，表示使用懒加载，
 * 表现的效果是：页面迅速打开（第一次打开页面无效），并使用上一次的数据展示，只有请求响应回来才更新页面数据
 */
class Lazyloader {
  constructor(controller, conditions) {
    // 定义的接口数据的2种类型：list和form
    let apis = [];
    apis.push(...this.fillUrls(controller.urls.model, 'form'));
    apis.push(...this.fillUrls(controller.urls.query, 'list'));
    let querys = []; // 请求promise
    let lazys = []; // 缓存数据promise
    // 追加参数，controller.$params表示url的?后面的查询参数
    let params = _.extend({}, controller.$params, conditions || {});
    _.each(apis, (api, idx) => {
        // 把该请求的所有参数作为key，然后看缓存里有没有
        let key = this.appendParams(api.url, params);
        let old = controller.$framework.store.get(key);
        if (old) {
          let p = new Promise((r) => {
            r(old);
          });
          lazys.push(p);
        }
        // 借助于loader.js来发请求
        let loader = new controller.$framework.Loader(controller, api);
        let waiting = loader.query(params);
        if (controller.$util.isPromise(waiting)) {
          let p = new Promise((rs, rj) => {
            waiting.then((v) => {
              // 把响应回来的数据缓存
              controller.$framework.store.set(key, v);
              rs(v);
            }, (v) => {
              rj(v);
            });
          });
          querys.push(p);
        }
        // 设置进controller的loaders数组里
        controller.setLoader(loader);
    });

    this.querys = querys;
    this.lazys = lazys;
    this.controller = controller;
  }


  // constructor(controller, conditions) {
  //   // 定义的接口数据的2种类型：list和form
  //   let apis = [{
  //     type: "list", // controller.urls.query的接口将作为列表数据
  //     urls: controller.$util.buildArray(controller.urls.query)
  //   }, {
  //     type: "form", // controller.urls.model的接口将作为表单数据
  //     urls: controller.$util.buildArray(controller.urls.model)
  //   }];
  //   console.log("--apis: ", apis);
  //   let querys = []; // 请求promise
  //   let lazys = []; // 缓存数据promise
  //   // 追加参数，controller.$params表示url的?后面的查询参数
  //   let params = _.extend({}, controller.$params, conditions || {});
  //   console.log('--params', params);
  //   _.each(apis, (a) => {
  //     console.log("--a", a);
  //     _.each(a.urls, (u, i) => {
  //       console.log("--u", u, "--i", i);
  //       // 把该请求的所有参数作为key，然后看缓存里有没有
  //       let key = this.appendParams(u, params);
  //       console.log('--key', key);
  //       let old = controller.$framework.store.get(key);
  //       if (old) {
  //         let p = new Promise((r) => {
  //           r(old);
  //         });
  //         lazys.push(p);
  //       }
  //       // 借助于loader.js来发请求
  //       let loader = new controller.$framework.Loader(controller, a.type, u, i);
  //       let waiting = loader.query(params);
  //       if (controller.$util.isPromise(waiting)) {
  //         let p = new Promise((rs, rj) => {
  //           waiting.then((v) => {
  //             // 把响应回来的数据缓存
  //             controller.$framework.store.set(key, v);
  //             rs(v);
  //           }, (v) => {
  //             rj(v);
  //           });
  //         });
  //         querys.push(p);
  //       }
  //       // 设置进controller的loaders数组里
  //       controller.setLoader(loader);
  //     });
  //   });
  // 
  //   this.querys = querys;
  //   this.lazys = lazys;
  //   this.controller = controller;
  // }

  
  // 填充url，最终的对象为：{ url: '', method: 'post', type: '', index: 1, priority: 1 }
  fillUrls(target, prefix) {
    let urls = []
    if(!target) {
      return urls;
    }

    if(_.isString(target)) {
      // 字符串
      urls.push({ url: target, method: 'post', type: prefix, index: '', priority: 1 });
    } else if (_.isArray(target)) {
      // 数组
      target.forEach((item, idx)=> {
        if (_.isString(item)) {
          urls.push({ url: item, method: 'post', type: prefix, index: idx, priority: 1 })
        } else {
          urls.push(
            _.extend({}, { url: '', method: 'post', priority: 1 }, item, { type: prefix, index: idx })
          )
        }
      })
    } else {
      // json对象
      urls.push(
        _.extend({}, { url: '', method: 'post', priority: 1 }, target, { type: prefix, index: '' })
      )
    } 
    return urls
  }
  appendParams(url, params) {
    for (var o in params) {
      var joinChar = url.indexOf("?") == -1 ? "?" : "&";
      url += joinChar;
      url += o + "=" + (params[o] || '');
    }
    return url;
  }
  load(resolve, reject, preloader = true, isNew = false, context = {}) {
    //初始化页面参数 ------------新增
    if (isNew) {
      _.extend(this.controller.context, context);
    }

    if (this.lazys.length == 0 && this.querys.length == 0) {
      // 缓存里没有，且无需发起请求，则直接resolve让页面跳转
      this.controller.bind({});
      resolve();
    } else {
      // 是否禁用controller缓存
      let isDisableCache = this.controller.disableCache();
      if (!isDisableCache && this.lazys.length > 0) {
        Promise.all(this.lazys)
          .then((values) => {
            this.controller.bind(values);
            this.controller.$$(".infinite-scroll-preloader").hide();
            // 只有resolve了页面才跳转
            resolve();
          }, (values) => {
            if (preloader) {
              this.controller.$f7.dialog.toast("请求数据失败，请稍后重试");
            }
            reject(values || "请求数据失败，请稍后重试");
          });
      } else if (preloader) {
        // this.controller.$f7.preloader.show();
      }
      // 页面请求还是会发
      // 如果没有禁用缓存，优先使用上次缓存数据显示，等请求响应回来才更新页面数据
      Promise.all(this.querys)
        .then((values) => {
          this.controller.bind(values);
          this.controller.reload = false;
          // this.controller.$f7.preloader.hide();
          this.controller.$$(".infinite-scroll-preloader").hide();
          if (isDisableCache || this.lazys.length == 0) {
            // 只有resolve了页面才跳转
            resolve();
          }
        }, (values) => {
          // this.controller.$f7.preloader.hide();
          if (isDisableCache || this.lazys.length == 0) {
            if (preloader) {
              this.controller.$f7.dialog.toast("请求数据失败，请稍后重试");
            }
            reject(values || "请求数据失败，请稍后重试");
          }
        })
        .catch(e => {
          console.error(e);
        });
    }
  }
}

export default Lazyloader;
